#include"../server.hpp"
#include<regex>
// #include<iostream>
// #include<mysql/mysql.h>

//test_for_buffer:
// int main()
// {
    // Buffer bf;
    // char arr[]="hello world";
    // bf.WriteData(arr,sizeof(arr)/sizeof(arr[0]));
    // Buffer cf(bf);
    // char brr[15],crr[20];
    // cf.ReadData(brr,sizeof(brr)/sizeof(brr[0]));
    // std::cout<<brr<<std::endl;
    // // bf.ReadDataAndPop(crr,sizeof(crr)/sizeof(crr[0]));
    // // std::cout<<len2<<crr<<std::endl;
    // std::string str=bf.ReadDataToStringAndPop(sizeof(arr)/sizeof(arr[0]));
    // std::cout<<str<<std::endl;

    // std::string s;
    // for(int i=1;i<=100;i++){
    //     s="i am one line code..."+std::to_string(i)+"\n";
    //     bf.WriteData(&s[0],s.size());
    // }
    //std::cout<<bf.ReadDataToStringAndPop(s.size()*100)<<std::endl;
    //Log(Info,"hello,this is a successful news,errno:%d,strerror:%s",errno,strerror(errno));
//     return 0;
// }
//------------------------------------------------------------------------------------------------
//test_for_timewheel
// void Print()
// {
//     std::cout<<"你好，我是测试函数..."<<std::endl;
// }

// int main()
// {
//     //测试
//     EventLoop eventloop;

//     eventloop.AddTimerTask(888,3,1,Print);//3秒后执行Print函数，如果有延迟指令，则延迟周期是5秒
    
//     while(1){
//         //tw.DelayTaskInOneLoop(888);
//         sleep(1);
//     }

//     return 0;
// }
// int main()
// {
//     int timerfd=timerfd_create(CLOCK_MONOTONIC,0);

//     struct itimerspec itime;
//     itime.it_value.tv_sec=1;
//     itime.it_value.tv_nsec=0;//1.0秒后触发一次“可读事件”
//     itime.it_interval.tv_sec=2;
//     itime.it_interval.tv_nsec=0;//第一次触发后，每隔1.0秒触发一次“可读事件”
//     timerfd_settime(timerfd,0,&itime,NULL);

//     int _epfd=epoll_create(128);
//     struct epoll_event eet;
//     eet.data.fd=timerfd;
//     eet.events=EPOLLIN;
//     epoll_ctl(_epfd,EPOLL_CTL_ADD,timerfd,&eet);

//     struct epoll_event _ready_fds[MAX_EVENTS];

//     int i=1;
//     while(1)
//     {
//         int ret=epoll_wait(_epfd,_ready_fds,MAX_EVENTS,-1);/*阻塞等待*/
//         if(ret>0){
//             uint64_t res;
//             int ret=read(timerfd,&res,sizeof(res));
//             std::cout<<"读取成功："<<i<<std::endl;
//         }
//     }

//     // std::cout<<"mysql client version:"<<mysql_get_client_info()<<std::endl;

//     return 0;
// }

#include"../http.hpp"
// static void Split(const std::string& str, const std::string sep, std::vector<std::string>& vv)
// {
//     int init_pos = 0, offset_pos = 0;

//     while (init_pos < str.size())
//     {
//         offset_pos = str.find(sep, init_pos);//以init_pos为起始点，开始寻找sep的位置
//         if (offset_pos == std::string::npos) {
//             vv.push_back(str.substr(init_pos));
//             break;
//         }
//         if(offset_pos!=init_pos) //分隔符与分隔符间没有字符串
//             vv.push_back(str.substr(init_pos, offset_pos - init_pos));//左闭右开区间
//         init_pos = offset_pos + sep.size(); //更新init_pos
//     }
// }

// static void ReadFromFile(const std::string& file_path,std::string& buffer)
// {
//     //1.以二进制的方式打开file_path文件
//     std::ifstream ifs(file_path.c_str(),std::ios::binary);
//     if(ifs.good()==false){
//         std::cout<<"ifstream open file fail!"<<std::endl;
//         return;
//     }
//     //2.计算ifs的长度:
//     ifs.seekg (0, ifs.end); //跳到ifs文件内数据的末尾
//     int length = ifs.tellg();//计算长度
//     // std::cout<<length<<std::endl;
//     ifs.seekg (0, ifs.beg); //跳回ifs文件内数据的初始位置
//     //3.读取数据到buffer中
//     buffer.resize(length);
//     ifs.read(&buffer[0],length);
//     //4.关闭文件
//     ifs.close();
// }

// static void WriteToFile(const std::string& file_path,std::string data)
// {
//     //1.以二进制的方式打开文件，如果文件原先有数据，则直接覆盖
//     std::ofstream ofs(file_path.c_str(),std::ios::binary | std::ios::trunc);
//     if(ofs.good()==false){
//         std::cout<<"ofstream open file fail!"<<std::endl;
//         return;
//     }
//     //2.向文件写入数据
//     ofs.write(data.c_str(),data.size());
//     //3.关闭文件
//     ofs.close();
// }

// static std::string UrlEncode(const std::string& str,bool turn_space_plus=false)
// {
//     std::string res;
//     for(auto& c:str)
//     {   
//         if(c=='.' || c=='-' || c=='_' || c=='~' || (c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z'))
//             res+=c;
//         else if(c==' ' && turn_space_plus==true)
//             res+='+';
//         else
//         {
//             char buf[4];
//             snprintf(buf,4,"%%%02X",c);
//             res+=buf;
//         }
//     }
//     return res;
// }

// static int HexToChar(char c)
// {
//     if(c>='0' && c<='9')return c-'0';
//     if(c>='a' && c<='z')return c-'a'+10;
//     if(c>='A' && c<='Z')return c-'A'+10;
//     return -1;
// }
// //Url解码：将%HH格式的数据转换成普通ASKII码字符  注意+是否需要特殊化处理
// static std::string UrlDecode(const std::string& str,bool turn_plus_to_space=false)
// {
//     std::string res;
//     for(int i=0;i<str.size();i++)
//     {
//         if(str[i]=='+' && turn_plus_to_space==true)
//             res+=' ';
//         else if(str[i]=='%' && i+2<str.size())
//         {
//             char ch=HexToChar(str[i+1])*16+HexToChar(str[i+2]);
//             res+=ch;
//             i+=2;
//         }
//         else res+=str[i];
//     }
//     return res;
// }

// int main()
// {
//     // std::string str = "abc,def,sda,,,,,,,";
//     // std::vector<std::string> vv;
//     // Split(str, ",", vv);
//     // for (const auto& str : vv)
//     //     std::cout << str << std::endl;

//     // std::string buffer;
//     // ReadFromFile("Any.cc",buffer);
//     // // std::cout<<buffer<<std::endl;

//     // WriteToFile("test.txt",buffer);

//     // std::string res=UrlEncode("a-=]././Z  ;'C  ",true);
//     // std::cout<<res<<std::endl;

//     std::string res=UrlDecode("C%2b%2b",true);
//     std::cout<<res<<std::endl;

//     return 0;
// }

//正则表达式测试
//int main()
//{
//    //Http请求行格式： 请求方法 + 资源路径 + 查询字符串 + 协议版本
//    //          例如：  GET /bitejiuyeke/login?user=xiaowang&password=123456789 HTTP/1.1\r\n
//    std::string line="GET /bitejiuyeke/login?user=xiaowang&password=123456789 HTTP/1.1\r\n";
//    
//    std::smatch matches;
//
//    //匹配并提取请求方法:GET HEAD POST PUT DELETE 
//    std::regex e("(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\?(.*))? (HTTP/1\\.[01])(?:\n|\r\n)?"); //.* 匹配除'\r'、'\r\n'外的所有字符串
//    //(GET|HEAD|POST|PUT|DELETE) 表示匹配并提取其中任意一个字符串
//    //([^?]*)     [^?]表示匹配非?字符  后面的*表示匹配次个或多次
//    //\\?(.*)     \\?表示原始的?字符   (.*)表示提取任意字符，直到遇到空格
//    //(HTTP/1//.[01])   //.表示原始的.字符   [01]表示匹配0或1
//    //(?:\r|\r\n)?    (?:\r|\r\n)表示匹配\r或\r\n，但是不提取   后面的?表示\r|\r\n可以不存在
//    //(?:\\?(.*))?    表示?和?后面的字符可能不存在，若存在的话则匹配，并且仅提取?后面的内容，不提取?本身
//
//    
//    bool ret=std::regex_search(line,matches,e);//按照匹配规则e，将从line字符串中提取到的子字符串存放在matches中
//    if(ret==false){
//        return false;
//    }
//
//    for(const auto& str:matches) std::cout<<str<<std::endl;
//    return 0;
//}

#define WWWROOT "./wwwroot/"
std::string RequestStr(const HttpRequest &req) 
{
    std::stringstream ss; ss << req._method << " " << req._path << " " << req._version << "\r\n"; 
    for (auto &it : req._goal_strs) 
        ss << it.first << ": " << it.second << "\r\n"; 
    for (auto &it : req._headers) 
        ss << it.first << ": " << it.second << "\r\n"; 
   
    ss << "\r\n"; ss << req._context; 
    return ss.str();
}
void Hello(const HttpRequest &req, HttpResponse *rsp) 
{
    rsp->SetContent(RequestStr(req), "text/plain");
}
void Login(const HttpRequest &req, HttpResponse *rsp) 
{
     rsp->SetContent(RequestStr(req), "text/plain");
}
void PutFile(const HttpRequest &req, HttpResponse *rsp) 
{
     std::string pathname = WWWROOT + req._path; 
     Util::WriteToFile(pathname, req._context);
}
void DelFile(const HttpRequest &req, HttpResponse *rsp) 
{
     rsp->SetContent(RequestStr(req), "text/plain");
}
int main()
{
     HttpServer server(8888); 
     server.SetStaticBaseDir(WWWROOT);
     server.SetGetHash("/hello", Hello);
     server.SetPostHash("/login", Login);
     server.SetPutHash("/1234.txt", PutFile);
     server.SetDeleteHash("/1234.txt", DelFile); 
     server.Start(); return 0;
}
